import { GpEcsWorld } from "../GpEcsWorld";
import { Sglt } from "../SgltDefine";
import { Comp } from "../CompDef";
import { Vect3 } from "../../../common/MathUtils";
import ecs, { EcsComponent } from "ecs-ts";
import { Vec3 } from "cc";

export class GpCmd<T> {
    constructor(
        public frame: number,
        public type: GpCmdType,
        public data: T
    ) { }
}

export enum GpCmdType {
    changeTargetDirection,
    setAttTarget,
    switchDoubleSpeed
}

export namespace GpCmdDataDef {
    export class ChangeTargetDirection {
        constructor(
            public entityId: number,
            public direction: Vec3
        ) { }
    }
    export class SetAttTarget {
        constructor(
            public entityId: number,
            public targetEntityId:number
        ) { }
    }

    export class SwitchSpeedUp {
        constructor(
            public entityId: number,
            public enable: boolean,
        ) { }
    }
}

/**命令系统 */
export class GpCmdSystem extends ecs.EcsSystem<GpEcsWorld> {
    worldInfo: Sglt.WorldInfo
    cmdHandlerMap: Map<GpCmdType, (cmd: GpCmd<any>) => void> = new Map()
    constructor(world: GpEcsWorld, defaltGroupComps: (new () => EcsComponent)[] = []) {
        super(world, defaltGroupComps);
        this.worldInfo = this.world.getSingleton(Sglt.WorldInfo)
        this.initCmdHandler()
    }

    initCmdHandler() {
        this.cmdHandlerMap.set(GpCmdType.changeTargetDirection, this.changeTargetDirection)
        this.cmdHandlerMap.set(GpCmdType.setAttTarget, this.setAttTarget)
        this.cmdHandlerMap.set(GpCmdType.switchDoubleSpeed, this.switchDoubleSpeed)


    }
    switchDoubleSpeed(cmd: GpCmd<GpCmdDataDef.SwitchSpeedUp>) {
        const entity = this.world.getEntity(cmd.data.entityId)
        if (!entity) {
            return
        }
    }
    setAttTarget(cmd: GpCmd<GpCmdDataDef.SetAttTarget>) {
        const entity = this.world.getEntity(cmd.data.entityId)
        if (!entity) {
            return
        }
        entity.component(Comp.Battle.BattleInfo).attTargetEntityId = cmd.data.targetEntityId
        // console.log("setAttTarget", cmd.data.targetEntityId);
        
    }

    changeTargetDirection(cmd: GpCmd<GpCmdDataDef.ChangeTargetDirection>) {
        const entity = this.world.getEntity(cmd.data.entityId)
        if (!entity) {
            return
        }
        const compTransform = entity.component(Comp.Transform)
        const compMove = entity.component(Comp.Move)
        compMove.hasForceMoveTargetPos=false
        Vect3.set(compMove.targetDirection, cmd.data.direction.x, cmd.data.direction.y, cmd.data.direction.z)
    }


    public update(): void {
        const commandInfo = this.world.getSingleton(Sglt.CommandInfo)
        for (let i = commandInfo.currentCommandIndex; i < commandInfo.commandList.length; i++) {
            const cmd = commandInfo.commandList[i]
            if (cmd.frame <= this.world.frameCount) {
                this.execCmd(cmd)
                commandInfo.currentCommandIndex++
                if (this.worldInfo.isMaster) {
                    commandInfo.waitSyncCommandList.push(cmd)
                }
            } else {
                break
            }
        }
    }

    execCmd(cmd) {
        const handler = this.cmdHandlerMap.get(cmd.type)
        handler?.call(this, cmd)
    }


    addCmd(cmd: GpCmd<any>) {
        const commandInfo = this.world.getSingleton(Sglt.CommandInfo)
        commandInfo.commandList.push(cmd)
    }

    /**创建命令并添加到系统 */
    makeCmd<T = any>(type: GpCmdType, data: T) {
        const cmd = new GpCmd(this.world.frameCount, type, data)
        this.addCmd(cmd)
        return cmd
    }
}